﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace XFPPT.NET
{
    /// <summary>
    /// 接口鉴权
    /// </summary>
    public static class ApiAuthAlgorithm
    {
        private static readonly char[] MD5_TABLE = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

        /// <summary>
        /// 获取签名
        /// </summary>
        /// <param name="appId">签名的key</param>
        /// <param name="secret">签名秘钥</param>
        /// <param name="ts">时间戳</param>
        /// <returns>返回签名</returns>
        public static string GetSignature(string appId, string secret, long ts)
        {
            try
            {
                string auth = Md5(appId + ts);
                return HmacSHA1Encrypt(auth, secret);
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// HMAC-SHA1 加密
        /// </summary>
        /// <param name="encryptText">加密文本</param>
        /// <param name="encryptKey">加密键</param>
        /// <returns>加密结果</returns>
        private static string HmacSHA1Encrypt(string encryptText, string encryptKey)
        {
            try
            {
                var keyBytes = Encoding.UTF8.GetBytes(encryptKey);
                using (var hmac = new HMACSHA1(keyBytes))
                {
                    var textBytes = Encoding.UTF8.GetBytes(encryptText);
                    var hashBytes = hmac.ComputeHash(textBytes);
                    return Convert.ToBase64String(hashBytes);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Encryption failed: " + ex.Message);
            }
        }

        /// <summary>
        /// MD5 加密
        /// </summary>
        /// <param name="cipherText">待加密字符串</param>
        /// <returns>加密后的字符串</returns>
        private static string Md5(string cipherText)
        {
            try
            {
                using (var md5 = MD5.Create())
                {
                    var inputBytes = Encoding.UTF8.GetBytes(cipherText);
                    var hashBytes = md5.ComputeHash(inputBytes);

                    var result = new char[hashBytes.Length * 2];
                    int index = 0;
                    foreach (var b in hashBytes)
                    {
                        result[index++] = MD5_TABLE[(b >> 4) & 0xF];
                        result[index++] = MD5_TABLE[b & 0xF];
                    }

                    return new string(result);
                }
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
    }

}
